#include <commonTypes.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>

#define NB_ITER 1000
#define MAX_PREEMPTIONS 100  // 设定抢占次数为 100

// 函数声明
void *task_low(void *args);
void *task_high(void *args);

// POSIX 线程句柄
pthread_t task_low_handle, task_high_handle;

// 性能测量的时间变量
struct timespec start_time, end_time;

// 用于记录最大延迟的变量
long max_delay = 0;

// 用于计算延迟的结构体
struct timespec preemption_time[MAX_PREEMPTIONS];
int preemption_count = 0;

// 模拟工作负载的低优先级任务函数
void *task_low(void *args)
{
    int count = 0;
    printf("task_low start\n");
    while (count < NB_ITER)
    {
        // 模拟工作负载
        usleep(1000); // 延时 1 us
        count++;
    }
    printf("task_low end\n");
    return NULL;
}

// 高优先级任务函数
void *task_high(void *args)
{
    for (int i = 0; i < MAX_PREEMPTIONS; i++)
    {
        // 记录当前时间，用于计算延迟
        clock_gettime(CLOCK_MONOTONIC, &start_time);

        // 模拟高优先级任务的执行
        usleep(100);  // 模拟高优先级任务工作

        // 记录结束时间，计算延迟
        clock_gettime(CLOCK_MONOTONIC, &end_time);

        // 计算延迟时间
        long time_diff = (end_time.tv_sec - start_time.tv_sec) * 1000000000L + (end_time.tv_nsec - start_time.tv_nsec);
        long time_us = time_diff / 1000 - 100;/*减去工作延时时间获取切换时间*/

        // 更新最大延迟
        if (time_us > max_delay)
        {
            max_delay = time_us;
        }

        // 每100次抢占输出一次延迟
        preemption_time[preemption_count].tv_sec = end_time.tv_sec;
        preemption_time[preemption_count].tv_nsec = end_time.tv_nsec;
        preemption_count++;

        usleep(1000);  // 模拟高优先级任务工作
    }
    return NULL;
}

// 初始化测试并创建线程
void preempte_initialize_test()
{
    struct sched_param param;

    // 创建低优先级任务
    if (pthread_create(&task_low_handle, NULL, task_low, NULL) != 0)
    {
        perror("pthread_create task_low_handle err");
        return;
    }

    // 设置低优先级任务（使用 SCHED_RR，优先级 10）
    param.sched_priority = 10;  // 低优先级
    if (pthread_setschedparam(task_low_handle, SCHED_RR, &param) != 0)
    {
        perror("pthread_setschedparam task low err ");
        return;
    }

    // 创建高优先级任务
    if (pthread_create(&task_high_handle, NULL, task_high, NULL) != 0)
    {
        perror("pthread_create task high err");
        return;
    }

    // 设置高优先级任务（使用 SCHED_RR，优先级 99）
    param.sched_priority = 99;  // 高优先级
    if (pthread_setschedparam(task_high_handle, SCHED_RR, &param) != 0)
    {
        perror("pthread_setschedparam task high err");
        return;
    }

    // 记录开始时间，用于性能测量
    clock_gettime(CLOCK_MONOTONIC, &start_time);

    // 等待任务完成
    pthread_join(task_low_handle, NULL);
    pthread_join(task_high_handle, NULL);

    // 输出最大延迟
    printf("Maximum delay in 100 preemptions: %ld us\n", max_delay);

    printf("\ntest end!\n");
}

int userAppInit()
{
    preempte_initialize_test();
    return 0;
}

